﻿using Asion.Dapper.SqlBuilder;
using Dapper;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Asion.Dapper
{
    public interface IUpdateColumn<TEntity> : ICondition where TEntity : IEntity
    {
    }


    public class UpdateColumn<TEntity> : BaseCondition<TEntity>, IUpdateColumn<TEntity>, IGetSql where TEntity : IEntity
    {
        private IDictionary<string, string> columns;

        public UpdateColumn(IDictionary<string, string> columns)
        {
            this.columns = columns;
        }


        /// <summary>
        /// build Update cloumn by list
        /// </summary>
        /// <param name="cloumns"></param>
        /// <returns></returns>
        private string BuildSql()
        {
            if (columns == null || !columns.Any())
            {
                throw new ArgumentException("set column is not empty ");
            }
            var sql = new StringBuilder();
            sql.AppendFormat(" SET ");
            for (var i = 0; i < columns.Count(); i++)
            {
                var column = columns.ElementAt(i);
                var property = _custom_table_mappinghandle.GetColumnMapping(column.Key);
                if (property == null)
                {
                    throw new ArgumentException($"set column that {column.Key}  does not exist ");
                }

                var formula = ComplexOperatorFactory.GetComplexCondtionOperatorFormula(CondtionOperator.Set);
                var stringArray = new List<DbType>()                {                    DbType.String,                    DbType.DateTime,                    DbType.Date,                    DbType.DateTime2                };                sql.AppendFormat(formula, _encap_sulation.EncapSulation(property.DataColumnName), stringArray.Contains(property.DataColumnType) ? _encap_sulation.EncapCloumnValue(column.Value) : column.Value);

                sql.AppendFormat(", ");
            }
            if (sql.ToString().EndsWith(", "))
                sql.Remove(sql.Length - 2, 2);

            return sql.ToString();
        }

        public string GetSql()
        {
            return BuildSql();
        }


    }

 


    public class UpdateColumnConditionFactory<TEntity> : BaseCondition<TEntity> where TEntity : IEntity
    {
        public UpdateColumnConditionFactory(IUpdateColumn<TEntity> condtion, IEncapSulation encapSulation)
        {
            where = condtion;
            _encap_sulation = encapSulation;

        }

        private IUpdateColumn<TEntity> where;


        public string GetSql()
        {
            if (where is UpdateColumn<TEntity>)
            {
                var condtion = where as UpdateColumn<TEntity>;
                condtion.Build(_encap_sulation);
                return condtion.GetSql();
            }
            throw new NotImplementedException("column condition");
        }


    }


    public static class UpdateColumnConditionFactoryExtend
    {
        public static UpdateColumnConditionFactory<TEntity> Build<TEntity>(this IUpdateColumn<TEntity> condtion, IEncapSulation encapSulation) where TEntity : IEntity
        {
            return new UpdateColumnConditionFactory<TEntity>(condtion, encapSulation);
        }
    }
}
